import time
from typing import List
import asyncio

"""
238. 除自身以外数组的乘积
https://leetcode.cn/problems/product-of-array-except-self/description/?envType=study-plan-v2&envId=top-interview-150
"""
class Solution:

    async def productExceptSelf2(self, nums: List[int]) -> List[int]:
        length = len(nums)
        L, R, answer = [0] * length, [0] * length, [0] * length

        async def calculate_L():
            print(time.time())
            L[0] = 1
            for i in range(1, length):
                L[i] = nums[i - 1] * L[i - 1]

        async def calculate_R():
            print("2:",time.time())
            R[length - 1] = 1
            for i in reversed(range(length - 1)):
                R[i] = nums[i + 1] * R[i + 1]

        await asyncio.gather(calculate_L(), calculate_R())

        for i in range(length):
            answer[i] = L[i] * R[i]

        return answer
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        length = len(nums)

        # L 和 R 分别表示左右两侧的乘积列表
        L, R, answer = [0] * length, [0] * length, [0] * length

        # L[i] 为索引 i 左侧所有元素的乘积
        # 对于索引为 '0' 的元素，因为左侧没有元素，所以 L[0] = 1
        L[0] = 1
        for i in range(1, length):
            L[i] = nums[i - 1] * L[i - 1]

        # R[i] 为索引 i 右侧所有元素的乘积
        # 对于索引为 'length-1' 的元素，因为右侧没有元素，所以 R[length-1] = 1
        R[length - 1] = 1
        for i in reversed(range(length - 1)):
            R[i] = nums[i + 1] * R[i + 1]

        # 对于索引 i，除 nums[i] 之外其余各元素的乘积就是左侧所有元素的乘积乘以右侧所有元素的乘积
        for i in range(length):
            answer[i] = L[i] * R[i]

        return answer


if __name__ == '__main__':
    nums = [1, 2, 3, 4]
    result = asyncio.run(Solution().productExceptSelf2(nums))
    print(result)
    # print(Solution().productExceptSelf2(nums))

    # print(Solution().productExceptSelf([-1, 1, 0, -3, 3]))
    # print(Solution().productExceptSelf([0, 0]))
    # print(Solution().productExceptSelf([1, 0, 0]))
    # print(Solution().productExceptSelf([0, 0, 5]))